package com.lb.base.util;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.lang.Nullable;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 时间工具类
 *
 * @author xiemingzhi
 * @since 1.0
 */
public final class DateUtils {

    public static final DateTimeFormatter FORMATTER_YYYYMMDD = DateTimeFormatter.ofPattern("yyyyMMdd");
    public static final DateTimeFormatter FORMATTER_YYYYMMDDHHMM = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");
    public static final DateTimeFormatter FORMATTER_YYYY_MM_DD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter FORMATTER_YYYY_MM_DDHH_MM_SS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private DateUtils() {
    }

    public static String format(Date date, String pattern) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(pattern));
    }

    public static String nowYYYYMMDD() {
        return LocalDate.now().format(FORMATTER_YYYYMMDD);
    }

    public static String YYYYMMDDHHMMSS(LocalDateTime time) {
        return time.format(FORMATTER_YYYY_MM_DDHH_MM_SS);
    }

    public static String YYYYMMDDHHMM(LocalDateTime time) {
        return time.format(FORMATTER_YYYYMMDDHHMM);
    }

    public static Integer differenceDays(Date start, Date end) {
        return (int) ((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
    }

    public static Date changeDays(Date date, Integer days) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        return calendar.getTime();
    }

    @Nullable
    public static Long toSystemDefaultMilli(@Nullable LocalDateTime localDateTime) {
        return Optional.ofNullable(localDateTime)
                .map(time -> time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli())
                .orElse(null);
    }

    @Nullable
    public static LocalDateTime toLocalDateTime(@Nullable Date date, Integer hours) {
        return Optional.ofNullable(date)
                .map(time -> date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().plusHours(hours))
                .orElse(null);
    }

    @Nullable
    public static LocalDateTime toLocalDateTime(@Nullable Long mills) {
        return Optional.ofNullable(mills)
                .map(time -> LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()))
                .orElse(null);
    }

    public static LocalDateTime getNowLocalDateTime(Integer plusDays) {
        return ZonedDateTime.now().toLocalDateTime().plusDays(plusDays);
    }

    public static LocalDateTime parseLocalDateTime(String time) {
        return LocalDateTime.parse(time, FORMATTER_YYYY_MM_DDHH_MM_SS);
    }

//    public static void main(String[] args) {
////        String formatPattern = "yyyy-MM-dd HH:mm:ss";
////        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern).withZone(ZoneId.of("GMT"));
////
////        Instant instant = Instant.now();
////        String date = formatter.format(instant);
////        System.out.println("格式化前 " + instant);
////        System.out.println("格式化后 " + date);
////        Student student = new Student(1, "hh", "男");
////        Student student1 = new Student(null,"","jjj");
////        BeanUtil.copyProperties(student1, student, CopyOptions.create().setIgnoreNullValue(true));
////        System.out.println(student);
////
////        BeanUtils.copyProperties(student1,student);
//        LocalDateTime now = LocalDateTime.now().plusDays(-15);
//        String format = DateUtil.format(now, DatePattern.NORM_DATETIME_PATTERN);
//        LocalDateTime latestTime = DateUtil.parseLocalDateTime(format, DatePattern.NORM_DATETIME_PATTERN);
//        long days = ChronoUnit.DAYS.between(latestTime, LocalDateTime.now());
//        System.out.println(days);
//
//    }

    static class ProbabilityLottery {
        private String[] prizes;
        private double[] probabilities;
        private Random random;

        public ProbabilityLottery(String[] prizes, double[] probabilities) {
            this.prizes = prizes;
            this.probabilities = probabilities;
            random = new Random();
        }

        public String draw() {
            double rand = random.nextDouble();
            double sum = 0.0;
            for (int i = 0; i < probabilities.length; i++) {
                sum += probabilities[i];
                if (rand < sum) {
                    return prizes[i];
                }
            }
            return null;
        }
    }

    public static void main(String[] args) {

        List<Student> list = new ArrayList<>();
        Map<Integer, Student> map = list.stream().collect(Collectors.toMap(Student::getAge, Function.identity()));
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class Student {

        private Integer age;

        private String name;

        private String gender;

    }

}
